﻿#ifndef DATACONTROL_H
#define DATACONTROL_H

#include <QObject>
#include <QSerialPort>
#include <QTimer>
#include <QHash>
#include <QDateTime>
#include <QMetaType>

// Exam: .\hub4com.exe --baud=115200 --octs=off \\.\COM6 \\.\COM9 \\.\COM11

using BaudRate = QSerialPort::BaudRate;
using DataBits = QSerialPort::DataBits;
using Parity =   QSerialPort::Parity;
using StopBits = QSerialPort::StopBits;
using FlowControl = QSerialPort::FlowControl;

// 端口信息
struct PortConfig {
    QString portName;
    BaudRate baudRate;
    DataBits dataBits;
    Parity parity;
    StopBits stopBits;
    FlowControl flowControl;

    PortConfig(const QString& portName, BaudRate baudRate)
        : portName(portName)
        , baudRate(baudRate)
        , dataBits(DataBits::Data8)
        , parity(Parity::NoParity)
        , stopBits(StopBits::OneStop)
        , flowControl(FlowControl::NoFlowControl)
    {}
};

// 每个端点的统计信息
struct EndpointStats {
    quint64 rxBytes = 0;
    quint64 txBytes = 0;
    quint64 rxPackets = 0;
    quint64 txPackets = 0;
    quint64 errorCount = 0;
    double  rxBps = 0.0;
    double  txBps = 0.0;
};

// 总体统计信息
struct TransferStats {
    quint64 inputRxBytes = 0;      // 物理输入口读取的字节数
    quint64 inputTxBytes = 0;      // 写回到物理输入口的字节数（来自端点）
    quint64 outputsTxBytes = 0;    // 转发到所有端点的总写字节数
    quint64 endpointsRxBytes = 0;  // 所有端点读取的总字节数

    quint64 inputRxPackets = 0;
    quint64 inputTxPackets = 0;
    quint64 outputsTxPackets = 0;
    quint64 endpointsRxPackets = 0;

    quint64 totalErrors = 0;       // 所有端口累计错误数

    double  inputRxBps = 0.0;
    double  inputTxBps = 0.0;
    double  outputsTxBps = 0.0;
    double  endpointsRxBps = 0.0;

    QDateTime lastUpdated;         // 最近一次统计更新时间
};

// 为带逗号的模板类型定义别名，避免 Q_DECLARE_METATYPE 形参分割
using EndpointStatsMap = QHash<QString, EndpointStats>;

Q_DECLARE_METATYPE(EndpointStats)
Q_DECLARE_METATYPE(TransferStats)
Q_DECLARE_METATYPE(EndpointStatsMap)

class DataControl : public QObject
{
    Q_OBJECT
public:
    explicit DataControl(QObject *parent = nullptr);

    ~DataControl();

    void initialization();

    bool setInputPort(const PortConfig& portConfig);

    bool addEndPointPort(const PortConfig& ePortConfig);

    bool startService();

    bool stopService();

    bool cleanService();

    bool sendToInputPort(const QByteArray &data);

    bool sendToAllEndpoints(const QByteArray &data);

    bool sendToEndpointPort(const QString &portName, const QByteArray &data);

    const QList<PortConfig> endPortsList();

    // 统计控制
    void resetStats();

signals:
    void InputPortDataReceived(const QByteArray &data);

    void EndPointPortDataReceived(const QString &portName, const QByteArray &data);

    void error(const QString &errMsg);

    // 周期性发送传输质量统计快照
    void StatsUpdated(const TransferStats &total, const EndpointStatsMap &perEndpoint);

private slots:
    void onInputReadyRead();

    void onOutputReadyRead(QSerialPort* port);

    void onStatsTimerTick();

private:
    QSerialPort* createSerialPort(const PortConfig& portConfig, QIODevice::OpenModeFlag mode);

    void forwardToOutputs(const QByteArray &data);

    void forwardToInput(const QByteArray &data);

    void startStats();
    void stopStats();

private:
    static QSerialPort      *sm_inputPort;
    QList<QSerialPort*>     m_EndPointsPortList;

    // 统计相关成员
    QTimer                  *m_statsTimer = nullptr;
    QDateTime               m_lastStatsTs;

    TransferStats            m_totalStats;
    QHash<QString, EndpointStats> m_perEndpointStats;

    // 用于计算速率的上次计数
    quint64 m_prevInputRxBytes = 0;
    quint64 m_prevInputTxBytes = 0;
    quint64 m_prevOutputsTxBytes = 0;
    quint64 m_prevEndpointsRxBytes = 0;
    QHash<QString, quint64> m_prevEpRxBytes;
    QHash<QString, quint64> m_prevEpTxBytes;
};

#endif // DATACONTROL_H
